﻿using Sidvall.Data;
using Sidvall.Serialization;
using System.Collections.Generic;
using System.Linq;

namespace Sidvall.UI.Entities
{
    public class ChartItemDataValueCollection : BusinessBaseCollection<ChartItemDataValue>
    {
        #region Public Members

        #region AddOrUpdate

        public ChartItemDataValue AddOrUpdate(string name, double? value)
        {
            return AddOrUpdate(name, value, null);
        }
        public ChartItemDataValue AddOrUpdate(string name, double? value, string category)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;
            var item = FindItem(name);
            if (item != null)
            {
                item.Name = name;
                item.Value = value;
                item.Category = category;
            }
            else
            {
                item = new ChartItemDataValue()
                {
                    Name = name,
                    Value = value,
                    Category = category,
                };
                Add(item);
            }
            return item;
        }

        #endregion
        #region FindItem

        public ChartItemDataValue FindItem(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
                return null;
            return (from o in this
                    where o.Name.Equals(name, true, System.StringComparison.OrdinalIgnoreCase)
                    select o).FirstOrDefault();
        }

        #endregion
        #region GetValue

        public double? GetValue(AggregationOperator aggregationOperator)
        {
            return GetValue(aggregationOperator, null);
        }
        public double? GetValue(AggregationOperator aggregationOperator, string category)
        {
            double[] values;

            if (string.IsNullOrWhiteSpace(category))
            {
                values = (from o in this
                          where (o.Value != null)
                          select o.Value.Value).ToArray();
            }
            else
            {
                values = (from o in this
                          where (o.Value != null) && (o.Category == category)
                          select o.Value.Value).ToArray();
            }
            if (values.Length == 0)
                return null;
            switch (aggregationOperator)
            {
                case AggregationOperator.Sum:
                    return values.Sum();
                case AggregationOperator.Average:
                    return values.Average();
                case AggregationOperator.Max:
                    return values.Max();
                case AggregationOperator.Min:
                    return values.Min();
                default:
                    throw new System.ArgumentException("Invalid aggregation operator");
            }
        }

        #endregion
        #region Remove

        public bool Remove(string name)
        {
            var item = FindItem(name);
            if (item != null)
                return Remove(item);
            return false;
        }
        public void Remove(IEnumerable<string> names)
        {
            if (names == null)
                return;
            foreach (var name in names)
                Remove(name);
        }

        #endregion
        #region Update

        public bool Update(string name, double? value)
        {
            var item = FindItem(name);
            if (item != null)
            {
                item.Value = value;
                return true;
            }
            return false;
        }

        #endregion

        #region Deserialize

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public static ChartItemDataValueCollection Deserialize(string value)
        {
            return Sidvall.Serialization.SerializerManager.Current.TryDeserialize<ChartItemDataValueCollection>(value, () =>
            {
                return new ChartItemDataValueCollection();
            });
        }

        #endregion
        #region Serialize

        public string Serialize()
        {
            return Serialize(this);
        }
        public static string Serialize(ChartItemDataValueCollection item)
        {
            return Sidvall.UI.Serialization.SerializerManager.Current.SerializeBusinessObject(item, Sidvall.Serialization.Formatting.None, true, true);
        }

        #endregion

        #endregion
        #region Constructors

        public ChartItemDataValueCollection()
        {
        }

        #endregion
    }
}
